package com.xianniu.ltc.aspect;

import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Record;
import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rebuild.core.Application;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.configuration.ConfigBean;
import com.rebuild.core.configuration.general.FormsBuilder;
import com.rebuild.core.configuration.general.FormsManager;
import com.rebuild.core.metadata.EntityRecordCreator;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.privileges.UserService;
import com.rebuild.web.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author wangruijie
 * 实体新增/修改保存触发切面操作
 *
 */
@Slf4j
@Aspect
@Component
public class SaveIRecordBeforeAspect extends BaseController {

    @Resource
    private HttpServletRequest request;

    private String[] idTypeList = {"REFERENCE", "CLASSIFICATION", "PICKLIST"};

    //拦截指定的方法,这里指只拦截TestService.getResultData这个方法
    @Pointcut("execution(public * com.rebuild.web.general.GeneralOperatingController.save(..))")
    public void excuteService() {

    }

    //执行方法前的拦截方法
    @Around("excuteService()")
    public Object doBeforeMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取目标方法的参数信息
        Object[] obj = joinPoint.getArgs();
        JSONObject jsonObject = new JSONObject();
        boolean viaSingle = getBoolParameter(request, "single");
        if (viaSingle) {
            log.info("数据详情打开后的单字段修改开始");
            jsonObject = doUpdateSaveRecord(obj[1]);
        }else {
            // 针对实体可添加"可重复子模块"，对子模块中数据的负值进行处理
            log.info("数据Form表单打开后的单字段修改开始");
            jsonObject = doRepeatable(obj[1]);
        }
        obj[1] = JSON.toJSON(jsonObject);
        return joinPoint.proceed(obj);
    }

    private JSONObject doUpdateSaveRecord(Object object){
        JSONObject json = JSONObject.parseObject(object.toString());
        Object o = json.get(EntityRecordCreator.META_FIELD);
        JSONObject object1 = (JSONObject) o;
        if (object1.get("id") != null){
            String recordId = object1.get("id").toString();
            if(!Objects.isNull(recordId)){
                // 过滤出 实体编码
                Integer entityCode = Integer.parseInt(recordId.substring(0, 3));
                Record record = getRecordByAdmin(entityCode, recordId);
                if(Objects.isNull(record)){
                    return json;
                }
                // 原汇总总金额
                BigDecimal hejizongjine = record.getDecimal("hejizongjine");
                // 不存在可重复文本字段的忽略操作
                String s = record.getString("kechongfuwenben");
                if (Objects.isNull(s)){
                    log.info("可重复文本数据为空--------》无需处理");
                    return json;
                }
                JSONArray jsonArray = JSONArray.parseArray(s);
                // 获取本次修改所有的<k>值
                Set<String> keys = json.keySet();
                // 获取"可重复字段"目前的值并解析成集合进行遍历
                Iterator it = jsonArray.iterator();
                while (it.hasNext()) {
                    Object itO = it.next();
                    for (String k : keys) {
                        JSONObject job = (JSONObject) itO;
                        // 本次修改的字段存在可重复文本中，则重新赋值
                        if (job.getString("field").equalsIgnoreCase(k)) {
                            if (object1.getString("entity").equalsIgnoreCase("xiangmuleibaoxiaoshenpi")
                                    && k.startsWith("rbjine9")){
                                // 项目类报销审批，汇总金额 = 报销金额的累加
                                BigDecimal rbjine9 = job.getBigDecimal("value");
                                // 汇总总金额 = 原汇总总金额-修改明细的原报销金额+本次修改后新的报销金额
                                hejizongjine = hejizongjine.subtract(rbjine9).add(json.getBigDecimal(k));
                            }
                            job.put("value", json.get(k));
                        }
                    }
                }
                json.put("hejizongjine", hejizongjine);
                json.put("kechongfuwenben", jsonArray);
                log.info("修改可重复文本数据结束--------》{}",json);
            }
        }
        return json;
    }

    /**
     * admin查询record记录
     * @param entityCode
     * @param recordId
     * @return
     */
    private Record getRecordByAdmin(Integer entityCode, String recordId){
        // 商机类型条件：目前仅商机使用，查询指定layout布局
        String conditions = null;
        // 实体
        Entity mEntity = MetadataHelper.getEntity(entityCode);
        // 租户编码
        String tenantCode = UserContextHolder.getTenant();
        // 超级管理员ID
        ID user = UserService.ADMIN_USER;
        // 商机
        if (mEntity.getName().equalsIgnoreCase("rbshangji4")){
            // 如果是商机，根据ID查询商机类型的值
            Object[] object = Application.createQueryNoFilter(
                    "select shangjileixing from rbshangji4 where rbshangji4Id = ? and tenantCode = ?")
                    .setParameter(1, ID.valueOf(recordId))
                    .setParameter(2, tenantCode)
                    .unique();
            conditions = String.valueOf(object[0]);
        }
        // 实体配置
        ConfigBean model = FormsManager.instance.getFormLayout(mEntity.getName(), user, tenantCode, conditions);
        // 实体配置元素
        JSONArray elements = (JSONArray) model.getJSON("elements");
        // 查询到的记录
        Record data = FormsBuilder.instance.findRecord(ID.valueOf(recordId), user, elements, tenantCode);
        return data;
    }

    /**
     * 功能描述: 针对实体可添加"可重复子模块"，对子模块中数据的负值进行处理
     *
     * @Param: [data]
     * @Return: void
     * @Author: wrj
     * @Date: 2022/3/14 2:43 下午
     */
    private JSONObject doRepeatable(Object object){
        log.info("修改可重复文本数据开始--------》");
        BigDecimal hejizongjine = BigDecimal.ZERO;
        JSONObject json = JSONObject.parseObject(object.toString());
        JSONObject entity = json.getJSONObject("metadata");
        Object o = json.get("kechongfuwenben");
        JSONArray saveArray = new JSONArray();
        if (o != null){
            JSONArray jsonArray = JSONArray.parseArray(o.toString());
            for (Object ob: jsonArray) {
                JSONObject job = (JSONObject) ob;
                if (job.getString("field").equalsIgnoreCase("$DIVIDER$")){
                    saveArray.add(job);
                }else {
                    JSONObject saveObj = new JSONObject();
                    if (job.getString("fixedField") != null){
                        saveObj.put("fixedField", job.getString("fixedField"));
                    }
                    saveObj.put("field", job.getString("field"));
                    saveObj.put("type", job.getString("type"));
                    if (Arrays.asList(idTypeList).contains(job.getString("type"))){
                        String idV = json.getString(job.getString("field"));
                        if (StringUtils.isNotBlank(idV)){
                            saveObj.put("value", ID.valueOf(idV));
                        }else {
                            saveObj.put("value", null);
                        }
                    }else {
                        saveObj.put("value", json.get(job.getString("field")));
                    }
                    // 项目类报销审批，汇总金额 = 报销金额的累加
                    if (entity.getString("entity").equalsIgnoreCase("xiangmuleibaoxiaoshenpi")
                        && job.getString("field").startsWith("rbjine9")){
                        log.info("项目类报销审批，汇总金额 = 报销金额的累加开始");
                        BigDecimal rbjine9 = json.getBigDecimal(job.getString("field"));
                        hejizongjine = rbjine9.add(hejizongjine);
                    }
                    saveArray.add(saveObj);
                }
            }
            json.put("hejizongjine", hejizongjine);
            json.put("kechongfuwenben", saveArray);
            log.info("修改可重复文本数据结束--------》{}",json);
        }
        return json;
    }

}